package com.iyouqu.dycm.search.utils;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aliyun.opensearch.DocumentClient;
import com.aliyun.opensearch.OpenSearchClient;
import com.aliyun.opensearch.SearcherClient;
import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Lists;
import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Maps;
import com.aliyun.opensearch.sdk.dependencies.org.json.JSONArray;
import com.aliyun.opensearch.sdk.dependencies.org.json.JSONObject;
import com.aliyun.opensearch.sdk.generated.OpenSearch;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchResult;
import com.aliyun.opensearch.sdk.generated.document.Command;
import com.aliyun.opensearch.sdk.generated.document.DocumentConstants;
import com.aliyun.opensearch.sdk.generated.search.Config;
import com.aliyun.opensearch.sdk.generated.search.Order;
import com.aliyun.opensearch.sdk.generated.search.Rank;
import com.aliyun.opensearch.sdk.generated.search.SearchFormat;
import com.aliyun.opensearch.sdk.generated.search.SearchParams;
import com.aliyun.opensearch.sdk.generated.search.Sort;
import com.aliyun.opensearch.sdk.generated.search.SortField;
import com.aliyun.opensearch.sdk.generated.search.general.SearchResult;
import com.iyouqu.dycm.search.bean.Search;

public class OpenSearchUtil {
	public static final Logger log = LoggerFactory.getLogger(OpenSearchUtil.class);
	private static String appName = PropUtil.getProperty("search.opensearch.appName", "");
	private static String tableName = PropUtil.getProperty("search.opensearch.tableName", "");
	private static String accesskey = PropUtil.getProperty("search.opensearch.accesskey", "");
	private static String secret = PropUtil.getProperty("search.opensearch.secret", "");
	private static String host = PropUtil.getProperty("search.opensearch.host",
			"http://opensearch-cn-hangzhou.aliyuncs.com");

	private static OpenSearch openSearch;
	private static OpenSearchClient serviceClient;
	private static DocumentClient documentClient;
	private static SearcherClient searcherClient;
	private static Config config;
	private static JsonValidator jsonValidator;

	static {
		openSearch = new OpenSearch(accesskey, secret, host);
		serviceClient = new OpenSearchClient(openSearch);
		documentClient = new DocumentClient(serviceClient);
		searcherClient = new SearcherClient(serviceClient);

		config = new Config(Lists.newArrayList(appName));
		config.setStart(0);
		config.setHits(10);
		config.setSearchFormat(SearchFormat.JSON);
		config.setFetchFields(Lists.newArrayList("ad_id"));
		jsonValidator = new JsonValidator();
	}

	public static boolean checkOpensearch() {
		return !(openSearch == null);
	}

	public static List<String> searchCity(String ad_type, String city, Long date, Long hour) {
		try {

			SearchParams searchParams = new SearchParams(config);

			searchParams.setQuery("ad_type:'" + ad_type + "' AND default:'" + city + "'");

			// 设置查询过滤条件
			searchParams.setFilter("start_time <= " + date + " AND ((start_hour1 <= " + hour + " AND end_hour1 >= "
					+ hour + ") OR (start_hour2 <= " + hour + " AND end_hour2 >= " + hour + "))");

			// 设置粗精排表达式，此处设置为默认
			Rank rank = new Rank();
			rank.setFirstRankName("default");
			rank.setReRankSize(6);// 设置参与精排文档个数
			// 添加排对象参数
			searchParams.setRank(rank);

			// 设置sort条件
			Sort sorter = new Sort();
			sorter.addToSortFields(new SortField("RANK", Order.DECREASE)); // 若id相同则以RANK降序
			sorter.addToSortFields(new SortField("price", Order.DECREASE)); // 设置降序
			sorter.addToSortFields(new SortField("hot", Order.DECREASE)); // 设置降序
			// 添加Sort对象参数
			searchParams.setSort(sorter);

			SearchResult searchResult = searcherClient.execute(searchParams);
			String result = searchResult.getResult();

			if (jsonValidator.validate(result)) {
				JSONObject obj = new JSONObject(result);
				if (obj != null) {
					JSONObject obj2 = obj.getJSONObject("result");

					if (obj2 != null) {

						JSONArray jary = obj2.getJSONArray("items");

						if (jary != null && jary.length() > 0) {
							List<String> list = Lists.newArrayList();
							for (int i = 0; i < jary.length(); i++) {
								JSONObject obj3 = jary.getJSONObject(i);

								if (obj3 != null) {
									list.add(obj3.get("ad_id").toString());
								}

							}

							return list;
						}
					}
				}
			} else {
				log.error("dycm-search.OpenSearchUtil.searchCity() result is not validate json str ");
			}

		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.searchCity() : " + e);
		}
		return null;
	}

	public static boolean add(Search obj) {
		try {
			Map<String, Object> doc1 = Maps.newHashMap();
			doc1.put("ad_id", obj.getAd_id());
			doc1.put("ad_type", obj.getAd_type());
			doc1.put("hot", obj.getHot());
			doc1.put("price", obj.getPrice());
			doc1.put("start_time", obj.getStart_time());

			doc1.put("end_time", obj.getEnd_time());
			doc1.put("start_hour1", obj.getStart_hour1());
			doc1.put("end_hour1", obj.getEnd_hour1());
			doc1.put("start_hour2", obj.getStart_hour2());
			doc1.put("end_hour2", obj.getEnd_hour2());

			doc1.put("city", array2String(obj.getCity()));
			doc1.put("city_code", array2Jary(obj.getCity_code()));
			doc1.put("attr_keywords", array2Jary(obj.getAttr_keywords()));
			doc1.put("title", obj.getTitle());
			doc1.put("description", obj.getDescription());

			JSONObject json1 = new JSONObject();
			json1.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
			json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);
			JSONArray docsJsonArr = new JSONArray();
			docsJsonArr.put(json1);// 新增文档1
			String docsJson = docsJsonArr.toString();
			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.add() : " + e);
		}
		return false;

	}

	public static boolean add(List<Search> list) {
		try {
			JSONArray docsJsonArr = new JSONArray();

			if (list != null && list.size() > 0) {
				for (Search obj : list) {
					Map<String, Object> doc1 = Maps.newHashMap();
					doc1.put("ad_id", obj.getAd_id());
					doc1.put("ad_type", obj.getAd_type());
					doc1.put("hot", obj.getHot());
					doc1.put("price", obj.getPrice());
					doc1.put("start_time", obj.getStart_time());

					doc1.put("end_time", obj.getEnd_time());
					doc1.put("start_hour1", obj.getStart_hour1());
					doc1.put("end_hour1", obj.getEnd_hour1());
					doc1.put("start_hour2", obj.getStart_hour2());
					doc1.put("end_hour2", obj.getEnd_hour2());

					doc1.put("city", array2String(obj.getCity()));
					doc1.put("city_code", array2Jary(obj.getCity_code()));
					doc1.put("attr_keywords", array2Jary(obj.getAttr_keywords()));
					doc1.put("title", obj.getTitle());
					doc1.put("description", obj.getDescription());

					JSONObject json1 = new JSONObject();
					json1.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
					json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);

					docsJsonArr.put(json1);// 新增文档1
				}
			}

			String docsJson = docsJsonArr.toString();
			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.add() : " + e);
			e.printStackTrace();
		}
		return false;

	}

	public static boolean update(Search obj) {
		try {
			JSONArray docsJsonArr = new JSONArray();

			Map<String, Object> doc1 = Maps.newHashMap();
			doc1.put("ad_id", obj.getAd_id());
			doc1.put("ad_type", obj.getAd_type());
			doc1.put("hot", obj.getHot());
			doc1.put("price", obj.getPrice());
			doc1.put("start_time", obj.getStart_time());

			doc1.put("end_time", obj.getEnd_time());
			doc1.put("start_hour1", obj.getStart_hour1());
			doc1.put("end_hour1", obj.getEnd_hour1());
			doc1.put("start_hour2", obj.getStart_hour2());
			doc1.put("end_hour2", obj.getEnd_hour2());

			doc1.put("city", array2String(obj.getCity()));
			doc1.put("city_code", array2Jary(obj.getCity_code()));
			doc1.put("attr_keywords", array2Jary(obj.getAttr_keywords()));
			doc1.put("title", obj.getTitle());
			doc1.put("description", obj.getDescription());

			JSONObject json1 = new JSONObject();
			json1.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
			json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);

			docsJsonArr.put(json1);// 新增文档1

			String docsJson = docsJsonArr.toString();
			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.update() : " + e);
			e.printStackTrace();
		}
		return false;

	}

	public static boolean update(String ad_id) {
		try {
			JSONArray docsJsonArr = new JSONArray();

			Map<String, Object> doc1 = Maps.newHashMap();
			doc1.put("ad_id", ad_id);
			doc1.put("start_time", DateUtil.getYmdTime() + 24 * 60 * 60 * 1000L);

			JSONObject json1 = new JSONObject();
			json1.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
			json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);

			docsJsonArr.put(json1);// 新增文档1

			String docsJson = docsJsonArr.toString();
			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.update() : " + e);
			e.printStackTrace();
		}
		return false;

	}

	public static boolean update(List<Search> list) {
		try {
			JSONArray docsJsonArr = new JSONArray();

			if (list != null && list.size() > 0) {
				for (Search obj : list) {
					Map<String, Object> doc1 = Maps.newHashMap();
					doc1.put("ad_id", obj.getAd_id());
					doc1.put("ad_type", obj.getAd_type());
					doc1.put("hot", obj.getHot());
					doc1.put("price", obj.getPrice());
					doc1.put("start_time", obj.getStart_time());

					doc1.put("end_time", obj.getEnd_time());
					doc1.put("start_hour1", obj.getStart_hour1());
					doc1.put("end_hour1", obj.getEnd_hour1());
					doc1.put("start_hour2", obj.getStart_hour2());
					doc1.put("end_hour2", obj.getEnd_hour2());

					doc1.put("city", array2String(obj.getCity()));
					doc1.put("city_code", array2Jary(obj.getCity_code()));
					doc1.put("attr_keywords", array2Jary(obj.getAttr_keywords()));
					doc1.put("title", obj.getTitle());
					doc1.put("description", obj.getDescription());

					JSONObject json1 = new JSONObject();
					json1.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
					json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);

					docsJsonArr.put(json1);// 新增文档1
				}
			}

			String docsJson = docsJsonArr.toString();

			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.update() : " + e);
			e.printStackTrace();
		}
		return false;

	}

	public static boolean delete(String ad_id) {
		try {
			Map<String, Object> doc1 = Maps.newLinkedHashMap();
			doc1.put("ad_id", ad_id);
			JSONObject json1 = new JSONObject();
			json1.put(DocumentConstants.DOC_KEY_CMD, Command.DELETE.toString());
			json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);
			JSONArray docsJsonArr = new JSONArray();
			docsJsonArr.put(json1);
			String docsJson = docsJsonArr.toString();
			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.delete() : " + e);
			e.printStackTrace();
		}
		return false;

	}

	public static boolean delete(List<String> ad_ids) {
		try {
			JSONArray docsJsonArr = new JSONArray();

			for (String ad_id : ad_ids) {
				Map<String, Object> doc1 = Maps.newLinkedHashMap();
				doc1.put("ad_id", ad_id);
				JSONObject json1 = new JSONObject();
				json1.put(DocumentConstants.DOC_KEY_CMD, Command.DELETE.toString());
				json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);
				docsJsonArr.put(json1);
			}

			String docsJson = docsJsonArr.toString();
			OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
			if (osr.getResult().equalsIgnoreCase("true")) {
				return true;
			}
		} catch (Exception e) {
			log.error("dycm-search.OpenSearchUtil.delete() : " + e);
			e.printStackTrace();
		}
		return false;

	}

	public static JSONArray array2Jary(Object[] objs) {
		JSONArray jary = new JSONArray();
		if (objs != null && objs.length > 0) {
			for (Object object : objs) {
				jary.put(object);
			}
		}
		return jary;
	}

	public static String array2String(Object[] objs) {
		String res = "";
		if (objs != null && objs.length > 0) {
			for (Object object : objs) {
				res += object.toString() + ",";
			}
		}
		if (res.length() > 0) {
			res = res.substring(0, res.length() - 1);
		}
		return res;
	}

}
